package tp.badugi.net;

/**
 * The listener interface for receiving status updates from server.
 * The class that is interested in processing an action request implements this interface.
 * When a status update occurs the corresponding method is invoked.
 * 
 * @author bartek
 *
 */
public interface iStatusUpdateListener {
	
	/**
	 * Indicates that a player folded. 
	 */
	public static final String ACTION_FOLD = iRequestListener.ACTION_FOLD;
	
	/**
	 * Indicates that a player checked. 
	 */
	public static final String ACTION_CHECK = iRequestListener.ACTION_CHECK;
	
	/**
	 * Indicates that a player made a bet. 
	 */
	public static final String ACTION_BET = iRequestListener.ACTION_BET;
	
	/**
	 * Indicates that a player called. 
	 */
	public static final String ACTION_CALL = iRequestListener.ACTION_CALL;
	
	/**
	 * Indicates that a player raised. 
	 */
	public static final String ACTION_RAISE = iRequestListener.ACTION_RAISE;
	
	/**
	 * Indicates that a player went all-in. 
	 */
	public static final String ACTION_ALLIN = iRequestListener.ACTION_ALLIN;
	
	/**
	 * This method is invoked when the player is dealt cards or when
	 * he receives replacement cards.
	 * <p>
	 * The cards parameter is a String array representing his current hand.
	 * Each card is represented by a two-character String. The first
	 * character signifies the rank (2, 3, 4, 5, 6, 7, 8, 9, T, J, Q, K, A).
	 * And the second character signifies the suit (S, H, D, C).
	 * For example "QS" means a queen of spades.
	 * 
	 * @param cards array containing the player's current 4 cards.
	 */
	public void receivedCards(String[] cards);
	
	/**
	 * This method is invoked when a new player connects to the server.
	 * This should only occur before the game begins. After the game begins
	 * new players are not allowed to join.
	 * 
	 * @param playerIndex the index of the player that joined the game.
	 * @param gameStatus object containing all the information about the game.
	 */
	public void playerJoined(
			int playerIndex, 
			GameStatus gameStatus);
	
	/**
	 * This method is invoked when a player leaves the game or when
	 * the server removes a disconnected player from the game because
	 * of a connection timeout.
	 * @param playerName the name of the player that left the game.
	 * @param gameStatus object containing all the information about the game.
	 */
	public void playerLeft(
			String playerName,
			GameStatus gameStatus);
	
	/**
	 * This method is invoked when a player gets disconnected during the game.
	 * When a player gets disconnected the game continues as if the player 
	 * folds every time it is his turn to act.
	 * <p>
	 * The player is given the ability to reconnect. If he reconnects before the connection
	 * times out the {@link #playerReconnected(String) playerReconnected} 
	 * method is invoked.
	 * @param playerName name of the player that got disconnected.
	 */
	public void playerDisconnected(String playerName);
	
	/**
	 * This method is invoked when a disconnected player reconnects before
	 * the server removes him from the game.
	 * @param playerName name of the player that reconnected.
	 */
	public void playerReconnected(String playerName);
	
	/**
	 * This method is invoked whenever the player in action changes.
	 * 
	 * @param playerIndex the index of the player in action.
	 * @param playerNames names of all the players.
	 */
	public void playerInActionChanged(int playerIndex, String[] playerNames);
	
	/**
	 * This method is invoked whenever the player with the button changes.
	 * 
	 * @param playerIndex the index of the player with button.
	 * @param playerNames names of all the players.
	 */
	public void playerWithButtonChanged(int playerIndex, String[] playerNames);
	
	/**
	 * This method is invoked whenever a player makes an action.
	 * <p>
	 * The full set of actions a player can perform are:
	 * {@link #ACTION_FOLD}, {@link #ACTION_CHECK}, {@link #ACTION_BET},
	 * {@link #ACTION_CALL}, {@link #ACTION_RAISE}, or {@link #ACTION_ALLIN}.
	 * 
	 * @param playerIndex the index of the player that performed the action.
	 * @param action action performed (one of the above).
	 * @param amount amount bet, amount raised, amount all-in, or 0 otherwise
	 * @param gameStatus object containing all the information about the game.
	 */
	public void playerPerformedAction(
			int playerIndex,
			String action, 
			long amount,
			GameStatus gameStatus
	);
	
	/**
	 * This method is invoked whenever a player chooses to have some of his cards replaced.
	 * <p>
	 * This information is provided so that other players can know how many cards
	 * each player has exchanged.
	 * @param playerName the name of the player that exchanged his cards.
	 * @param cardCount the number of cards that the player exchanged.
	 */
	public void playerReplacedCards(String playerName, int cardCount);
	
	/**
	 * This method is invoked whenever the next betting round begins or a new game starts.
	 * 
	 * @param bettingRound the current betting round or 0 if the game hasn't started.
	 */
	public void bettingRoundChanged(int bettingRound);
	
	/**
	 * This method is invoked when the showdown takes place and all remaining players
	 * reveal their cards.
	 * @param winnerIndexes the indexes of the players that won the pot.
	 * @param playerNames the name of each player.
	 * @param revealedCards two-dimensional array containing the cards of all the players.
	 * @param updatedChipCounts the updated amount of chips each player has after the pot
	 * has been divided among the winners.
	 */
	public void winnerRevealed(
			int[] winnerIndexes,
			String[] playerNames, 
			String[][] revealedCards, 
			long[] updatedChipCounts
	);
	
	/**
	 * This method is invoked when the connection with the server is lost.
	 */
	public void connectionLostWithServer();

	/**
	 * This method is invoked when the cards will be dealt soon and the table is giving
	 * players notice to get ready.
	 * 
	 * @param timeUntilStart time before the cards will be dealt in seconds.
	 * @param gameStatus object containing all the information about the game.
	 */
	public void gameAboutToStart(int timeUntilStart, GameStatus gameStatus);

	public void gameAboutToRestart(int timeUntilRestart);
	
}
